package com.ahearttogo.result;

import com.ahearttogo.binding.MapperMethod;
import org.apache.ibatis.reflection.factory.DefaultObjectFactory;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

/**
 * @author xiejialin
 * @date 2020/4/22 10:09 AM
 * 拿到结果集，进行反射赋值
 */

public class DefaultResultSetHandler implements ResultSetHandler{
    @Override
    public   <T> T handle(PreparedStatement pstmt, MapperMethod mapperMethod) throws SQLException,
            NoSuchMethodException,
            InvocationTargetException, IllegalAccessException{
       Object resultObject = new DefaultObjectFactory().create(mapperMethod.getType());
        ResultSet rs = pstmt.getResultSet();
        if(rs.next()) {
            int i = 0;
            for(Field field : resultObject.getClass().getDeclaredFields()){
                setValue(resultObject,field,rs,i);
            }
        }
        return (T) resultObject;
    }

    private void setValue(Object resultObject, Field field, ResultSet rs, int i) throws SQLException,
            InvocationTargetException, IllegalAccessException, NoSuchMethodException {
        Method setMethod = resultObject.getClass().getMethod("set" + upperCapital(field.getName()), field.getType() );
        setMethod.invoke(resultObject,getResult(field,rs));
    }

    private Object getResult(Field field, ResultSet rs) throws SQLException {
        Class<?> type = field.getType();
        if(Integer.class == type){
            return rs.getInt(field.getName());
        }
        if(String.class == type){
            return rs.getString(field.getName());
        }
        if(Long.class==type){
            return  rs.getLong(field.getName());
        }
        return rs.getString(field.getName());
    }

    private String upperCapital(String name) {
        String first = name.substring(0, 1);
        String tail = name.substring(1);
        return first.toUpperCase() + tail;
    }
}
